/*
 * This file Copyright (c) 2015. Walle.
 * (http://www.wallellen.com). All rights reserved.
 *
 *
 * This file is dual-licensed under both the
 * Walle Agreement (WA) and the GNU General Public License.
 * You may elect to use one or the other of these licenses.
 *
 * This file is distributed in the hope that it will be
 * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
 * Redistribution, except as permitted by whichever of the GPL
 * or WA you select, is prohibited.
 *
 * 1. For the GPL license (GPL), you can redistribute and/or
 * modify this file under the terms of the GNU General
 * Public License, Version 3, as published by the Free Software
 * Foundation.  You should have received a copy of the GNU
 * General Public License, Version 3 along with this program;
 * if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * 2. For the Walle Agreement (WA), this file
 * and the accompanying materials are made available under the
 * terms of the WA which accompanies this distribution, and
 * is available at http://www.wallellen.com/agreement.html
 *
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 */

package com.wallellen.knowledge.know.service.impl;

import com.wallellen.authority.domain.User;
import com.wallellen.core.auth.domain.LoginUser;
import com.wallellen.core.sql.query.DBRule;
import com.wallellen.core.sql.query.DBSort;
import com.wallellen.core.sql.query.DataQuery;
import com.wallellen.core.time.TimeTool;
import com.wallellen.knowledge.doc.domain.Doc;
import com.wallellen.knowledge.doc.domain.DocType;
import com.wallellen.knowledge.doc.domain.Docfile;
import com.wallellen.knowledge.doc.domain.ex.DocEntire;
import com.wallellen.knowledge.doc.exception.CanNoWriteException;
import com.wallellen.knowledge.doc.server.DocManagerInter;
import com.wallellen.knowledge.doc.server.DocOperateRightInter;
import com.wallellen.knowledge.doc.server.DocTypeInter;
import com.wallellen.knowledge.doc.server.FileManagerInter;
import com.wallellen.knowledge.know.service.KnowServiceInter;
import com.wallellen.knowledge.know.service.WebDocServiceInter;
import com.wallellen.knowledge.know.util.HttpResourceHandle;
import com.wallellen.lucene.face.WordAnalyzerFace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

/**
 * 文档管理
 *
 * @author <a href="mailto:wallellen@hotmail.com">WALLE</a>
 */
@Service
public class KnowServiceImpl implements KnowServiceInter {
    @Resource
    private DocManagerInter farmDocManagerImpl;
    @Resource
    private FileManagerInter farmFileManagerImpl;
    @Resource
    private DocOperateRightInter farmDocOperateRightImpl;
    @Resource
    private DocTypeInter farmDocTypeManagerImpl;

    @Override
    @Transactional
    public DocEntire creatKnow(String knowtitle, String knowtypeId, String text, String knowtag, DocOperateRightInter.POP_TYPE pop_type_edit,
                               DocOperateRightInter.POP_TYPE pop_type_read, String groupId, LoginUser currentUser) {
        DocEntire doc = new DocEntire(new Doc());
        doc.getDoc().setTitle(knowtitle);
        doc.setTexts(text, currentUser);
        doc.getDoc().setWritepop(pop_type_edit.getValue());
        doc.getDoc().setDocgroupid(groupId);
        doc.getDoc().setReadpop(pop_type_read.getValue());
        doc.getDoc().setTagkey(knowtag);
        doc.getDoc().setDomtype("1");
        doc.getDoc().setState("1");
        doc.getDoc().setPubtime(TimeTool.getTimeDate14());
        doc.setType(farmDocTypeManagerImpl.getType(knowtypeId));
        doc = farmDocManagerImpl.createDoc(doc, currentUser);
        return doc;
    }

    @Override
    @Transactional
    public DocEntire editKnow(String docid, String text, String knowtag, LoginUser currentUser, String editNote)
            throws CanNoWriteException {
        Doc doc = farmDocManagerImpl.getDocOnlyBean(docid);
        return editKnow(docid, doc.getTitle(), null, text, knowtag, DocOperateRightInter.POP_TYPE.getEnum(doc.getWritepop()),
                DocOperateRightInter.POP_TYPE.getEnum(doc.getReadpop()), doc.getDocgroupid(), currentUser, editNote);
    }

    @Override
    @Transactional
    public DocEntire editKnow(String id, String knowtitle, String knowtype, String text, String knowtag,
                              DocOperateRightInter.POP_TYPE pop_type_edit, DocOperateRightInter.POP_TYPE pop_type_read, String groupId, LoginUser currentUser, String editNote)
            throws CanNoWriteException {
        DocEntire entity = farmDocManagerImpl.getDoc(id);
        if (groupId != null && !groupId.isEmpty()) {
            entity.getDoc().setDocgroupid(groupId);
        }
        entity.getDoc().setTitle(knowtitle);
        entity.setTexts(text, currentUser);
        entity.getDoc().setTagkey(knowtag);
        entity.getDoc().setWritepop(pop_type_edit.getValue());
        entity.getDoc().setReadpop(pop_type_read.getValue());
        DocType type = farmDocTypeManagerImpl.getType(knowtype);
        entity.setType(type);
        entity = farmDocManagerImpl.editDocByUser(entity, editNote, currentUser);
        return entity;
    }

    @Override
    @Transactional
    public DocEntire getDocByWeb(String url, LoginUser user) {
        DocEntire doc = new DocEntire(new Doc());
        try {
            String[] webdocs = WebDocServiceImpl.instance().crawlerWebDocTempFileId(new URL(url),
                    WebDocServiceInter.DOC_TYPE.HTML, new HttpResourceHandle() {
                        @Override
                        public String handle(String eurl, URL baseUrl) {
                            // eurl=http://img.baidu.com/img/baike/logo-baike.png
                            String exname = null;
                            try {
                                if (eurl.lastIndexOf("?") > 0) {
                                    exname = eurl.substring(0, eurl.lastIndexOf("?"));
                                } else {
                                    exname = eurl;
                                }
                                if (eurl.lastIndexOf(".") > 0) {
                                    exname = eurl.substring(eurl.lastIndexOf(".") + 1);
                                } else {
                                    exname = eurl;
                                }
                                if (exname == null || exname.length() > 10) {
                                    exname = "gif";
                                }
                            } catch (Exception e) {
                                exname = "gif";
                            }
                            LoginUser thisuser = new LoginUser() {
                                @Override
                                public String getName() {
                                    return "NONE";
                                }

                                @Override
                                public String getLoginName() {
                                    return "NONE";
                                }

                                @Override
                                public String getId() {
                                    return "NONE";
                                }
                            };
                            if (eurl.toUpperCase().indexOf("HTTP") < 0) {
                                eurl = baseUrl.toString().substring(0, baseUrl.toString().lastIndexOf("/") + 1) + eurl;
                            }
                            try {
                                URL innerurl = new URL(eurl);
                                // 创建连接的地址
                                HttpURLConnection connection = (HttpURLConnection) innerurl.openConnection();
                                // 返回Http的响应状态码
                                InputStream input = null;
                                try {
                                    input = connection.getInputStream();
                                } catch (Exception e) {
                                    return eurl;
                                }
                                Docfile file = farmFileManagerImpl.openFile(exname,
                                        eurl.length() > 128 ? eurl.substring(0, 128) : eurl, thisuser);
                                OutputStream fos = new FileOutputStream(file.getFile());
                                // 获取输入流
                                try {
                                    int bytesRead = 0;
                                    byte[] buffer = new byte[8192];
                                    while ((bytesRead = input.read(buffer, 0, 8192)) != -1) {
                                        fos.write(buffer, 0, bytesRead);
                                    }
                                } finally {
                                    input.close();
                                    fos.close();
                                }
                                // config.file.client.html.resource.url
                                eurl = farmFileManagerImpl.getFileURL(file.getId());
                            } catch (IOException e) {
                                log.error(e + "网络图片文件保存失败", e);
                            }
                            return eurl;
                        }
                    });
            doc.getDoc().setTitle(webdocs[1]);
            String tag = null;
            List<Object[]> taglist = WordAnalyzerFace.parseHtmlWordCaseForSortList(webdocs[0]);
            for (Object[] Object : taglist.size() > 10 ? taglist.subList(0, 10) : taglist) {
                if (tag != null) {
                    tag = tag + ",";
                } else {
                    tag = "";
                }
                tag = tag + Object[0];
            }
            doc.getDoc().setTagkey(tag);
            doc.setTexts(webdocs[2], user);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return doc;
    }

    private static final Logger log = LoggerFactory.getLogger(KnowServiceImpl.class);

    @Override
    public DataQuery getMyDocQuery(DataQuery query, User user) {
        query = DataQuery
                .init(
                        query,
                        "farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID=b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID=a.ID LEFT JOIN farm_doctype d ON d.ID=c.TYPEID",
                        "a.ID as ID,a.STATE as STATE,a.TITLE AS title,a.DOCDESCRIBE AS DOCDESCRIBE,a.AUTHOR AS AUTHOR,a.PUBTIME AS PUBTIME,a.TAGKEY AS TAGKEY ,a.IMGID AS IMGID,b.VISITNUM AS VISITNUM,b.PRAISEYES AS PRAISEYES,b.PRAISENO AS PRAISENO,b.HOTNUM AS HOTNUM,b.EVALUATE as EVALUATE,b.ANSWERINGNUM as ANSWERINGNUM,d.NAME AS TYPENAME");
        query.addRule(new DBRule("a.STATE", "0", "!="));
        query.addRule(new DBRule("a.CUSER", user.getId(), "="));
        query.addSort(new DBSort("a.ctime", "desc"));
        return query;
    }
}
